<?php

namespace app\model\contract;

use app\model\BaseModel;

/**
 * 合同签署记录模型
 * 对应数据表：oa_contract_sign
 */
class ContractSign extends BaseModel
{
    /**
     * 数据表名
     * @var string
     */
    protected $name = 'contract_sign';

    /**
     * 主键名
     * @var string
     */
    protected $pk = 'id';

    /**
     * 字段类型转换
     * @var array
     */
    protected $type = [
        'id' => 'integer',
        'contract_id' => 'integer',
        'customer_id' => 'integer',
        'sign_type' => 'integer',
        'sign_status' => 'integer',
        'sign_time' => 'integer',
        'expire_time' => 'integer',
        'sign_user' => 'string',
        'sign_phone' => 'string',
        'sign_email' => 'string',
        'sign_ip' => 'string',
        'sign_file' => 'string',
        'sign_code' => 'string',
        'remark' => 'string',
        'create_time' => 'integer',
        'update_time' => 'integer',
    ];

    /**
     * 可搜索字段
     * @var array
     */
    protected $searchField = ['sign_user', 'sign_phone', 'sign_email', 'sign_code'];

    /**
     * 签署类型
     * @var array
     */
    public const SIGN_TYPE = [
        1 => '电子签署',
        2 => '线下签署',
        3 => '快递签署',
    ];

    /**
     * 签署状态
     * @var array
     */
    public const SIGN_STATUS = [
        1 => '待签署',
        2 => '签署中',
        3 => '已签署',
        4 => '已拒绝',
        5 => '已过期',
    ];

    /**
     * 关联合同
     * @return \think\model\relation\BelongsTo
     */
    public function contract()
    {
        return $this->belongsTo('app\model\contract\Contract', 'contract_id', 'id');
    }

    /**
     * 关联客户
     * @return \think\model\relation\BelongsTo
     */
    public function customer()
    {
        return $this->belongsTo('app\model\customer\Customer', 'customer_id', 'id');
    }

    /**
     * 获取签署记录列表
     * @param array $params 查询参数
     * @return array
     */
    public function getSignList($params = [])
    {
        $where = [];
        
        if (!empty($params['contract_id'])) {
            $where[] = ['contract_id', '=', $params['contract_id']];
        }
        
        if (!empty($params['customer_id'])) {
            $where[] = ['customer_id', '=', $params['customer_id']];
        }
        
        if (!empty($params['sign_type'])) {
            $where[] = ['sign_type', '=', $params['sign_type']];
        }
        
        if (isset($params['sign_status']) && $params['sign_status'] !== '') {
            $where[] = ['sign_status', '=', $params['sign_status']];
        }

        return $this->where($where)
            ->with(['contract', 'customer'])
            ->order('id', 'desc')
            ->paginate([
                'list_rows' => $params['limit'] ?? 15,
                'page' => $params['page'] ?? 1,
            ]);
    }

    /**
     * 创建签署记录
     * @param array $data 签署数据
     * @return bool|int
     */
    public function createSign($data)
    {
        $data['sign_code'] = $this->generateSignCode();
        $data['sign_status'] = 1; // 待签署
        $data['create_time'] = time();
        $data['update_time'] = time();
        
        return $this->insertGetId($data);
    }

    /**
     * 更新签署状态
     * @param int $id 记录ID
     * @param int $status 状态
     * @param array $extra 额外数据
     * @return bool
     */
    public function updateSignStatus($id, $status, $extra = [])
    {
        $updateData = [
            'sign_status' => $status,
            'update_time' => time(),
        ];

        if (isset($extra['sign_time'])) {
            $updateData['sign_time'] = $extra['sign_time'];
        }

        if (isset($extra['sign_ip'])) {
            $updateData['sign_ip'] = $extra['sign_ip'];
        }

        if (isset($extra['sign_file'])) {
            $updateData['sign_file'] = $extra['sign_file'];
        }

        if (isset($extra['remark'])) {
            $updateData['remark'] = $extra['remark'];
        }

        return $this->where('id', $id)->update($updateData);
    }

    /**
     * 获取待签署记录
     * @param int $customerId 客户ID
     * @return array
     */
    public function getPendingSigns($customerId = null)
    {
        $where = [
            ['sign_status', '=', 1], // 待签署
            ['expire_time', '>', time()]
        ];
        
        if ($customerId) {
            $where[] = ['customer_id', '=', $customerId];
        }

        return $this->where($where)
            ->with(['contract', 'customer'])
            ->order('expire_time', 'asc')
            ->select()
            ->toArray();
    }

    /**
     * 通过签署码获取记录
     * @param string $signCode 签署码
     * @return array|null
     */
    public function getBySignCode($signCode)
    {
        return $this->where('sign_code', $signCode)
            ->with(['contract', 'customer'])
            ->find();
    }

    /**
     * 验证签署码
     * @param string $signCode 签署码
     * @return bool
     */
    public function validateSignCode($signCode)
    {
        $record = $this->where('sign_code', $signCode)
            ->where('sign_status', 1)
            ->where('expire_time', '>', time())
            ->find();

        return !empty($record);
    }

    /**
     * 生成签署码
     * @return string
     */
    protected function generateSignCode()
    {
        return 'SIGN' . date('YmdHis') . mt_rand(1000, 9999);
    }

    /**
     * 获取签署统计
     * @param int $contractId 合同ID
     * @param int $customerId 客户ID
     * @return array
     */
    public function getSignStats($contractId = null, $customerId = null)
    {
        $where = [];
        
        if ($contractId) {
            $where[] = ['contract_id', '=', $contractId];
        }
        
        if ($customerId) {
            $where[] = ['customer_id', '=', $customerId];
        }

        $stats = $this->where($where)
            ->field('sign_type, sign_status, COUNT(*) as count')
            ->group('sign_type, sign_status')
            ->select()
            ->toArray();

        $result = [
            'total' => 0,
            'type_stats' => [],
            'status_stats' => []
        ];

        foreach ($stats as $stat) {
            $result['total'] += $stat['count'];
            
            if (!isset($result['type_stats'][$stat['sign_type']])) {
                $result['type_stats'][$stat['sign_type']] = 0;
            }
            $result['type_stats'][$stat['sign_type']] += $stat['count'];
            
            if (!isset($result['status_stats'][$stat['sign_status']])) {
                $result['status_stats'][$stat['sign_status']] = 0;
            }
            $result['status_stats'][$stat['sign_status']] += $stat['count'];
        }

        return $result;
    }

    /**
     * 删除签署记录
     * @param int|array $ids 记录ID
     * @return bool
     */
    public function deleteSign($ids)
    {
        if (is_array($ids)) {
            return $this->where('id', 'in', $ids)->delete();
        } else {
            return $this->where('id', $ids)->delete();
        }
    }

    /**
     * 搜索器：按合同ID搜索
     * @param \think\db\Query $query
     * @param int $value
     */
    public function searchContractIdAttr($query, $value)
    {
        $query->where('contract_id', $value);
    }

    /**
     * 搜索器：按客户ID搜索
     * @param \think\db\Query $query
     * @param int $value
     */
    public function searchCustomerIdAttr($query, $value)
    {
        $query->where('customer_id', $value);
    }

    /**
     * 搜索器：按签署类型搜索
     * @param \think\db\Query $query
     * @param int $value
     */
    public function searchSignTypeAttr($query, $value)
    {
        $query->where('sign_type', $value);
    }

    /**
     * 搜索器：按签署状态搜索
     * @param \think\db\Query $query
     * @param int $value
     */
    public function searchSignStatusAttr($query, $value)
    {
        $query->where('sign_status', $value);
    }

    /**
     * 搜索器：按签署用户搜索
     * @param \think\db\Query $query
     * @param string $value
     */
    public function searchSignUserAttr($query, $value)
    {
        $query->where('sign_user', 'like', '%' . $value . '%');
    }

    /**
     * 搜索器：按签署码搜索
     * @param \think\db\Query $query
     * @param string $value
     */
    public function searchSignCodeAttr($query, $value)
    {
        $query->where('sign_code', $value);
    }
}